#include "oscilloscopetool.h"
#include "ui_oscilloscopetool.h"

OscilloscopeTool::OscilloscopeTool(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OscilloscopeTool)
{
    ui->setupUi(this);

    waveWindowInit();
}

OscilloscopeTool::~OscilloscopeTool()
{
    delete ui;
}

void OscilloscopeTool::waveWindowInit(void)
{
    ui->widgetOsci->setBackground(QBrush(QColor(148, 148, 148)));
    ui->widgetOsci->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    ui->widgetOsci->yAxis->setRange(0, 3.3);
    ui->widgetOsci->axisRect()->setupFullAxesBox();

    ui->widgetOsci->legend->setVisible(true);
    ui->widgetOsci->legend->setBrush(QColor(100, 100, 100, 0));
    ui->widgetOsci->legend->setTextColor(Qt::white);

    if(ui->checkBoxCh1->checkState() == Qt::Checked)
    {
        graphCh1 = ui->widgetOsci->addGraph(ui->widgetOsci->xAxis, ui->widgetOsci->axisRect()->axis(QCPAxis::atRight, 1));
        graphCh1->setPen(QPen(QColor(0, 255, 0)));
        graphCh1->setName("ch1");
    }
    if(ui->checkBoxCh2->checkState() == Qt::Checked)
    {
        graphCh2 = ui->widgetOsci->addGraph(ui->widgetOsci->xAxis, ui->widgetOsci->axisRect()->axis(QCPAxis::atRight, 2));
        graphCh2->setPen(QPen(QColor(0, 0, 255)));
        graphCh2->setName("ch2");
    }
    if(ui->checkBoxCh3->checkState() == Qt::Checked)
    {
        graphCh3 = ui->widgetOsci->addGraph(ui->widgetOsci->xAxis, ui->widgetOsci->axisRect()->axis(QCPAxis::atRight, 3));
        graphCh3->setPen(QPen(QColor(255, 0, 0)));
        graphCh3->setName("ch3");
    }
    if(ui->checkBoxCh4->checkState() == Qt::Checked)
    {
        graphCh4 = ui->widgetOsci->addGraph(ui->widgetOsci->xAxis, ui->widgetOsci->axisRect()->axis(QCPAxis::atRight, 4));
        graphCh4->setPen(QPen(QColor(255, 255, 0)));
        graphCh4->setName("ch4");
    }
}

void OscilloscopeTool::wavaWindowDraw(double ch1Data, double ch2Data, double ch3Data, double ch4Data)
{
    if(ui->checkBoxCh1->checkState() == Qt::Checked)
    {
        qDebug() << "ch1Data";
        graphCh1->addData(graphCh1->dataCount(), ch1Data);
    }
    if(ui->checkBoxCh2->checkState() == Qt::Checked)
    {
        qDebug() << "ch2Data";
        graphCh2->addData(graphCh2->dataCount(), ch2Data);
    }
    if(ui->checkBoxCh3->checkState() == Qt::Checked)
    {
        qDebug() << "ch3Data";
        graphCh3->addData(graphCh3->dataCount(), ch3Data);
    }
    if(ui->checkBoxCh4->checkState() == Qt::Checked)
    {
        qDebug() << "ch4Data";
        graphCh4->addData(graphCh4->dataCount(), ch4Data);
    }

    // make key axis range scroll with the data:
    ui->widgetOsci->xAxis->rescale();
    graphCh1->rescaleValueAxis(false, true);
    graphCh2->rescaleValueAxis(false, true);
    graphCh3->rescaleValueAxis(false, true);
    graphCh4->rescaleValueAxis(false, true);

    ui->widgetOsci->xAxis->setRange(ui->widgetOsci->xAxis->range().upper, 100, Qt::AlignRight);
    ui->widgetOsci->replot();
}

void OscilloscopeTool::waveDataWrite(double ch1Data, double ch2Data, double ch3Data, double ch4Data)
{
    QString ch1Str = "ch1:" + QString::number(ch1Data, 'f', 6) + " ";
    QString ch2Str = "ch2:" + QString::number(ch2Data, 'f', 6) + " ";
    QString ch3Str = "ch3:" + QString::number(ch3Data, 'f', 6) + " ";
    QString ch4Str = "ch4:" + QString::number(ch4Data, 'f', 6);

    ui->textBrowserRecvData->append("{ " + ch1Str + ch2Str + ch3Str + ch4Str + " }");
}

uint8_t OscilloscopeTool::dataChecksum(float *data, uint16_t len)
{
    uint16_t index = 0;
    uint8_t checksum = 0;
    for(; index < len; index++)
    {
        checksum = (uint8_t)(checksum + data[index]);
    }
    return  checksum;
}

void OscilloscopeTool::dataProcessing(QByteArray array)
{
    OscPacket packet;

    if(array.data()[0] == 'R' && array.data()[1] == 'T')
    {
        memcpy_s(&packet, sizeof(OscPacket), (void *)array.data(), sizeof(OscPacket));
        wavaWindowDraw(packet.data[0], packet.data[1], packet.data[2], packet.data[3]);
        waveDataWrite(packet.data[0], packet.data[1], packet.data[2], packet.data[3]);
    }
}

void OscilloscopeTool::on_buttonSerialOpen_clicked()
{
    QString port = ui->comboBoxSerialPort->currentText().split(":")[0];
    if(ui->buttonSerialOpen->text() == tr("打开串口"))
    {
        serial.setPortName(port);
        serial.setBaudRate(ui->comboBoxSerialBaud->currentText().toInt());
        serial.setDataBits(QSerialPort::Data8);
        serial.setParity(QSerialPort::NoParity);
        serial.setStopBits(QSerialPort::OneStop);
        serial.setFlowControl(QSerialPort::NoFlowControl);
        if(serial.open(QIODevice::ReadWrite))
        {
            connect(&serial,SIGNAL(readyRead()),this,SLOT(serialRecv()));
            ui->buttonSerialOpen->setText(tr("关闭串口"));
            ui->comboBoxSerialPort->setEnabled(false);
            ui->comboBoxSerialBaud->setEnabled(false);
            ui->checkBoxCh1->setEnabled(false);
            ui->checkBoxCh2->setEnabled(false);
            ui->checkBoxCh3->setEnabled(false);
            ui->checkBoxCh4->setEnabled(false);
        }

    }
    else
    {
        serial.close();
        disconnect(&serial,SIGNAL(readyRead()),this,SLOT(serialRecv()));
        ui->buttonSerialOpen->setText(tr("打开串口"));
        ui->comboBoxSerialPort->setEnabled(true);
        ui->comboBoxSerialBaud->setEnabled(true);
        ui->checkBoxCh1->setEnabled(true);
        ui->checkBoxCh2->setEnabled(true);
        ui->checkBoxCh3->setEnabled(true);
        ui->checkBoxCh4->setEnabled(true);
    }
}

void OscilloscopeTool::serialRecv()
{
    if(serial.isOpen())
    {
        QByteArray array = serial.readAll();
        dataProcessing(array);
    }
}

void OscilloscopeTool::on_buttonNetOpen_clicked()
{
    if(ui->buttonNetOpen->text() == tr("打开网络"))
    {
        QString ip = ui->comboBoxNetIp->currentText();
        int port = ui->lineEditNetPort->text().toInt();
        tcpServer = new QTcpServer(this);
        if(tcpServer->listen(QHostAddress(ip), port))
        {
            connect(tcpServer, SIGNAL(newConnection()), this, SLOT(tcpConnect()));
            ui->buttonNetOpen->setText(tr("关闭网络"));
            ui->checkBoxCh1->setEnabled(false);
            ui->checkBoxCh2->setEnabled(false);
            ui->checkBoxCh3->setEnabled(false);
            ui->checkBoxCh4->setEnabled(false);


        }
        else
        {
            tcpServer->deleteLater();
            tcpServer = nullptr;
        }
    }
    else
    {
        ui->buttonNetOpen->setText(tr("打开网络"));
        if(serverSocket != nullptr && serverSocket->state() == QAbstractSocket::ConnectedState)
        {
            serverSocket->disconnectFromHost();
        }

        tcpServer->close();
        tcpServer->deleteLater();
        tcpServer = nullptr;
        ui->checkBoxCh1->setEnabled(true);
        ui->checkBoxCh2->setEnabled(true);
        ui->checkBoxCh3->setEnabled(true);
        ui->checkBoxCh4->setEnabled(true);
    }
}

void OscilloscopeTool::tcpConnect()
{
    if(tcpServer->hasPendingConnections())
    {
        serverSocket = tcpServer->nextPendingConnection();

        connect(serverSocket,SIGNAL(readyRead()),this,SLOT(tcpRecv()));
        connect(serverSocket,SIGNAL(disconnected()),this,SLOT(tcpDisconnect()));
        ui->textBrowserRecvData->append("客户端: IP-" + serverSocket->peerAddress().toString() \
                                        + " Port-" + QString::number(serverSocket->peerPort()));
    }
}

void OscilloscopeTool::tcpRecv()
{
    if(serverSocket != nullptr)
    {
        QByteArray array = serverSocket->readAll();
        dataProcessing(array);
    }
}

void OscilloscopeTool::tcpDisconnect()
{
    qDebug() << "tcpDisconnect";
    if(serverSocket != nullptr)
    {
        serverSocket->close();
        serverSocket->deleteLater();
        serverSocket = nullptr;
    }
}

void OscilloscopeTool::on_buttonClearData_clicked()
{
    ui->textBrowserRecvData->clear();
    ui->widgetOsci->clearGraphs();
    ui->widgetOsci->legend->setVisible(false);
    ui->widgetOsci->replot();

    waveWindowInit();
}

void OscilloscopeTool::on_buttonH_VZoom_clicked()
{
    ui->widgetOsci->axisRect()->setRangeZoom(Qt::Vertical | Qt::Horizontal);
}

void OscilloscopeTool::on_buttonHorizontalZoom_clicked()
{
    ui->widgetOsci->axisRect()->setRangeZoom(Qt::Horizontal);
}

void OscilloscopeTool::on_buttonVerticalZoom_clicked()
{
    ui->widgetOsci->axisRect()->setRangeZoom(Qt::Vertical);
}

void OscilloscopeTool::on_radioButtonSerial_clicked()
{
    ui->comboBoxSerialPort->setEnabled(true);
    ui->comboBoxSerialBaud->setEnabled(true);
    ui->buttonSerialOpen->setEnabled(true);

    ui->comboBoxNetIp->setEnabled(false);
    ui->lineEditNetPort->setEnabled(false);
    ui->buttonNetOpen->setEnabled(false);
}


void OscilloscopeTool::on_radioButtonNet_clicked()
{
    ui->comboBoxSerialPort->setEnabled(false);
    ui->comboBoxSerialBaud->setEnabled(false);
    ui->buttonSerialOpen->setEnabled(false);

    ui->comboBoxNetIp->setEnabled(true);
    ui->lineEditNetPort->setEnabled(true);
    ui->buttonNetOpen->setEnabled(true);
}

